package com.example.file

import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.ViewTreeObserver.OnScrollChangedListener
import android.widget.*
import android.widget.SeekBar.OnSeekBarChangeListener
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.net.InetSocketAddress
import java.nio.ByteBuffer
import java.nio.channels.SocketChannel
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.security.MessageDigest


internal class thr(var ty: Int, var upper: MainActivity, var ff: ByteArray, var port: Int) :
    Thread() {
    @RequiresApi(Build.VERSION_CODES.O)
    override fun run() {
        if (ty == 1)
            ty1()
        if (ty == 2)
            ty2()
    }

    fun ty2() {
        try {
            var a = SocketChannel.open()
            var add =
                InetSocketAddress("127.0.0.1", port)
            a.connect(add)
            var b = ByteBuffer.allocate(1)
            b.put(1)
            b.flip()
            a.write(b)
            b = ByteBuffer.allocate(4)
            b.putInt(ff.size)
            b.flip()
            a.write(b)
            b = ByteBuffer.wrap(ff)
            a.write(b)
            a.close()
            println("\nok")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun ty1() {
        try {
            var a = SocketChannel.open()
            var add =
                InetSocketAddress("127.0.0.1", port)
            a.connect(add)
            var b = ByteBuffer.allocate(1)
            b.put(0)
            b.flip()
            a.write(b)
            var totalLen = 0
            b = ByteBuffer.allocate(4)
            while (totalLen != 4)
                totalLen += a.read(b)
            b.flip()
            var l = b.getInt()
            println(l)
            b = ByteBuffer.allocate(l)
            totalLen = 0
            while (totalLen != l) {
                totalLen += a.read(b)
                println(totalLen)
            }
            a.close()
            var st = MessageDigest.getInstance("MD5").digest(b.array());
            for (i in 0 until st.size) {
                print("," + st[i])
            }
            upper.runOnUiThread { upper.write(b.array()) }
            println("\nok")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}

class MainActivity : AppCompatActivity() {
    fun del(ss: String): Boolean {
        return try {
            val path = baseContext.filesDir
            val f = File(path, ss)
            f.delete()
        } catch (e: java.lang.Exception) {
            return false
        }
    }

    fun get(ll:Int=-1): ByteArray {
        return try {
            var sp = findViewById<View>(R.id.fn_spin) as Spinner
            val ss: String = sp.getSelectedItem().toString()
            val path = baseContext.filesDir
            val f = File(path, ss)
            var l = f.length().toInt()
            val st = FileInputStream(f)
            if (ll>0)
                l = ll
            val x = ByteArray(l)
            st.read(x)
            st.close()
            x
        } catch (e: java.lang.Exception) {
            ByteArray(0)
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun write(b: ByteArray?) {
        try {
            var e = findViewById<View>(R.id.file_name) as EditText
            val ss = e.text.toString()
            val path = baseContext.filesDir
            val f = File(path, ss)
            val o = FileOutputStream(f)
            o.write(b)
            o.close()
            refreshSp()
        } catch (e: java.lang.Exception) {
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun refreshSp() {
        var sp = findViewById<View>(R.id.fn_spin) as Spinner
        var spinnerArray = ArrayList<String>();
        Files.list(baseContext.filesDir.toPath()).forEach {
            println(it)
            spinnerArray.add(it.fileName.toString())
        }
        var adapter = ArrayAdapter<String>(
            this, android.R.layout.simple_spinner_item, spinnerArray
        );

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sp.setAdapter(adapter);
    }

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate(savedInstanceState: Bundle?) {
        class yourListener : OnSeekBarChangeListener {
            override fun onProgressChanged(
                sk: SeekBar, progress: Int,
                fromUser: Boolean
            ) {
                if (!fromUser) return
                val scroll =
                    findViewById<View>(R.id.log_scroll) as ScrollView
                val xx =
                    scroll.getChildAt(0).bottom * progress.toFloat() / sk.max.toFloat()
                scroll.fling(0)
                val handler = Handler()
                handler.postDelayed({ scroll.scrollTo(0, xx.toInt()) }, 1)
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {}
            override fun onStopTrackingTouch(seekBar: SeekBar) {}
        }
        this.supportActionBar!!.hide()
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val sk = findViewById<View>(R.id.seekBar) as SeekBar
        sk.setOnSeekBarChangeListener(yourListener())
        val ss = findViewById<View>(R.id.log_scroll) as ScrollView
        ss.viewTreeObserver.addOnScrollChangedListener(OnScrollChangedListener {
            val scroll =
                findViewById<View>(R.id.log_scroll) as ScrollView
            val xx = scroll.getChildAt(0).bottom
            val jj = scroll.scrollY
            val sk = findViewById<View>(R.id.seekBar) as SeekBar
            if (xx > 0) {
                val ff = jj.toFloat() / xx
                sk.progress = (ff * sk.max).toInt()
            }
        })
        refreshSp()
        var e = findViewById<View>(R.id.new_ed) as EditText
        e.setText("")

        e = findViewById<View>(R.id.show_ed) as EditText
        e.setText("")
        e.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable) {}
            override fun beforeTextChanged(
                s: CharSequence, start: Int,
                count: Int, after: Int
            ) {
            }

            override fun onTextChanged(
                xxx: CharSequence, start: Int,
                before: Int, count: Int
            ) {
                var xx=xxx
                println(xx)
                var e = findViewById<View>(R.id.new_ed) as EditText
                var b = get(20000)
                val w = myBuf(b)
                val l: Int = w.readWord()
                var s =
                    String(w.readArr(l), StandardCharsets.UTF_8)
                var m = HashMap<String, Int>()
                println(s.length)
                for (lo in 0..s.length-1) {
                    m.put(s.substring(lo, lo + 1), lo)
                }
                var st = ""
                if(xx.toString()==".")
                {
                    xx="."+s
                }
                for (i in xx) {
                    if (i.toString() in m) {
                        var ii:Int = m[i.toString()]!!
                        st += i + Integer.toOctalString(ii)+" "
                    }
                }
                e.setText(st)
            }
        })

        var b = findViewById<View>(R.id.get_btn) as Button
        b.setOnClickListener {
            var e = findViewById<View>(R.id.port_ed) as EditText
            val aa = thr(1, this, ByteArray(0), e.text.toString().toInt())
            aa.setDaemon(true)
            aa.start()
        }
        b = findViewById<View>(R.id.send_btn) as Button
        b.setOnClickListener {
            var e = findViewById<View>(R.id.port_ed) as EditText
            val aa = thr(2, this, get(), e.text.toString().toInt())
            aa.setDaemon(true)
            aa.start()
        }
        b = findViewById<View>(R.id.sendnew_btn) as Button
        b.setOnClickListener {
            var e = findViewById<View>(R.id.new_ed) as EditText
            var sli = findViewById<View>(R.id.slice_ed) as EditText
            var bb = mk(e.text.toString(), sli.text.toString().toInt())
            var sh = findViewById<View>(R.id.show_ed) as EditText
            sh.setText(ret)
            var p = findViewById<View>(R.id.port_ed) as EditText
            val aa = thr(2, this, bb, p.text.toString().toInt())
            aa.setDaemon(true)
            aa.start()
            write(bb)
        }

        b = findViewById<View>(R.id.del_btn) as Button
        b.setOnClickListener {
            var sp = findViewById<View>(R.id.fn_spin) as Spinner
            val text: String = sp.getSelectedItem().toString()
            del(text)
            refreshSp()
        }
    }
}
